﻿using System;
using System.Collections.Generic;
using System.Xml.Linq;
using QASPRibbon.Commands;
using Schema = QASPRibbon.RibbonSchema;

namespace QASPRibbon.Controls
{
    /// <summary>
    /// Represents a Button control in the SharePoint Server Ribbon.
    /// </summary>
    public class RibbonButton : RibbonVisualControl
    {
        #region JavaScript

        /// <summary>
        /// Javascript code that executes when a Button is activated.
        /// </summary>
        public string OnClientActivate
        {
            get { return _onClientActivate; }
            set { _onClientActivate = value; }
        }

        /// <summary>
        /// Javascript code that executes when a Button's Click event is raised.
        /// </summary>
        public string OnClientClick
        {
            get { return _onClientClick; }
            set { _onClientClick = value; }
        }

        /// <summary>
        /// Javascript code that executes when a Button's enable/disable state is checked.
        /// </summary>
        public string OnClientStateCheck
        {
            get { return _onClientStateCheck; }
            set { _onClientStateCheck = value; }
        }

        #endregion

        #region Properties

        /// <summary>
        /// Alternative text for the button.
        /// </summary>
        public string Alt
        {
            get { return _alt; }
            set { _alt = value; }
        }

        /// <summary>
        /// The name of a CSS class selector to be applied to the control's label.
        /// </summary>
        public string TitleCss
        {
            get { return _titleCss; }
            set { _titleCss = value; }
        }

        #endregion

        #region Internal

        internal override XElement AsXElement()
        {
            var element = base.AsXElement();
            element.Add(new XAttribute(Schema.LabelText, Title));
            if (!string.IsNullOrEmpty(TitleCss))
                element.Add(new XAttribute(Schema.LabelCss, TitleCss));
            element.Add(!string.IsNullOrEmpty(TemplateAlias)
                            ? new XAttribute(Schema.TemplateAlias, TemplateAlias)
                            : new XAttribute(Schema.TemplateAlias, "o1"));
            element.Add(new XAttribute(Schema.MenuItemId, FullId));
            element.Add(new XAttribute(Schema.CommandValueId, FullId + Schema.Command));
            element.Add(new XAttribute(Schema.Command, FullId + Schema.Command));
            return element;
        }

        private RibbonVisualControl _parentMenu;
        internal RibbonVisualControl ParentMenu
        {
            get
            {
                return _parentMenu;
            }
            set
            {
                _parentMenu = value;
                if (_parentMenu is RibbonComboBox)
                {
                    _extraScript =
                        string.Format(
                            "var menuNode = document.getElementById('{0}'); var title='{1}'; menuNode.value=title;",
                            ParentMenu.FullId, Title);
                }
                else if (_parentMenu is RibbonDropDown)
                {
                    _extraScript =
                        string.Format(
                            "var menuNode = document.getElementById('{0}').parentNode.childNodes[0]; var title='{1}'; menuNode.innerHTML=title;",
                            ParentMenu.FullId, Title);
                }
            }
        }

        private string _extraScript;

        internal override IEnumerable<RibbonCommand> ClientCommands
        {
            get
            {
                var res = new List<RibbonCommand>();
                var postBackScript = string.Empty;
                if (AllowPostBack)
                {
                    if (this is RibbonCheckBox)
                    {
                        postBackScript = string.Format("__doPostBack('{0}', properties.On);", FullId);
                    }
                    else if (this is RibbonSpinner)
                    {
                        postBackScript = string.Format("__doPostBack('{0}', (properties.ChangedByMouse?'1':'0')+'|'+properties.ChangeType+'|'+Unit+'|'+Value);", FullId);
                    }
                    else if (ParentMenu != null)
                    {
                        postBackScript = string.Format("__doPostBack('{0}', title);", FullId);
                    }
                    else
                    {
                        postBackScript = string.Format("__doPostBack('{0}', '');", FullId);
                    }
                }
                res.Add(new RibbonCommand(FullId, RibbonSchema.CheckState, string.Format("{0}; {1}; return {2};", OnClientActivate ?? string.Empty, OnClientStateCheck, Enabled ? "true" : "false")));
                res.Add(new RibbonCommand(FullId, Schema.Command, string.Format("{0}{1}; {2}", _extraScript, OnClientClick ?? string.Empty, (AllowPostBack ? postBackScript : string.Empty))));
                
                return res;
            }
        }

        internal override string XmlTag
        {
            get { return Schema.Button; }
        }

        internal bool AllowPostBack
        {
            get
            {
                var handler = OnAction;
                return handler != null;
            }
        }

        #endregion

        #region Constructors

        /// <summary>
        /// Creates and initializes a new instance of the RibbonButton.
        /// </summary>
        public RibbonButton() { }

        /// <summary>
        /// Creates and initializes a new instance of the RibbonButton.
        /// </summary>
        /// <param name="id">Identifier</param>
        public RibbonButton(string id) : base(id) { }

        /// <summary>
        /// Creates and initializes a new instance of the RibbonButton.
        /// </summary>
        /// <param name="id">Identifier</param>
        /// <param name="title">Title</param>
        public RibbonButton(string id, string title) : base(id, title) { }

        #endregion

        #region Private

        private string _onClientActivate = string.Empty;
        private string _onClientClick = string.Empty;
        private string _onClientStateCheck = string.Empty;
        private string _alt = string.Empty;
        private string _titleCss = string.Empty;

        #endregion

        #region PostBack Action

        /// <summary>
        /// Occurs when the Button control is clicked.
        /// </summary>
        public event RibbonButtonEventHandler OnAction;

        internal void DoOnAction(RibbonButtonActionEventArgs e)
        {
            var handler = OnAction;
            if (handler != null) handler(this, e);
        }

        #endregion
    }

    /// <summary>
    /// RibbonButton event handler
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e">Event arguments</param>
    public delegate void RibbonButtonEventHandler(object sender, RibbonButtonActionEventArgs e);

    /// <summary>
    /// Arguments of server ation rised by RibbonButton
    /// </summary>
    public class RibbonButtonActionEventArgs : EventArgs
    {
        /// <summary>
        /// Instance of RibbonButton
        /// </summary>
        public RibbonButton Instance;

        internal RibbonButtonActionEventArgs(RibbonButton button)
        {
            Instance = button;
        }
    }
}
